/*
* Copyright (C) 2021 ~ 2022 Uniontech Technology Co., Ltd.
*
* Author:      zhangbingyi <zhangbingyi@uniontech.com>
*
* Maintainer:  zhangbingyi <zhangbingyi@uniontech.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "securitylevelwidget.h"
#include "securitylevelmodel.h"
#include "securitylevelchangedialog.h"
#include "switchaccounttipdialog.h"
#include "widgets/titlebuttonitem.h"
#include "widgets/titledslideritem.h"
#include "widgets/dccslider.h"
#include "securitylevelitem.h"
#include "configuratingsystemleveldialog.h"
#include "executingdialog.h"
#include "privilegeseparationdialog.h"
#include "securitylevelchangedefinition.h"
#include "systemlevelpolicykit.h"
#include "waylandwarningdialog.h"

//#include <DTipLabel>
//#include <DFrame>
//#include <DFontSizeManager>

#include <QVBoxLayout>
//#include <QScroller>
#include <QScrollBar>
#include <QScrollArea>
#include <QLabel>

SecurityLevelWidget::SecurityLevelWidget(QWidget *parent)
    : QFrame(parent)
    , m_layout(new QVBoxLayout)
    , m_highLevelItem(nullptr)
    , m_mediumLevelItem(nullptr)
    , m_lowLevelItem(nullptr)
    , m_securityLevelModel(new SecurityLevelModel(this))
    , m_systemLevelStartDialog(nullptr)
    , m_executingDialog(nullptr)
    , m_policyKit(nullptr)
{
    this->setAccessibleName("rightWidget_securityLevelWidget");

    initUI();

    // thread
    m_policyKit = new SystemLevelPolicyKit;
    m_policyKit->moveToThread(&m_polKitThread);
    connect(this, SIGNAL(requestConfirmChangeSystemLevel(int)), m_policyKit, SLOT(confirmSystemLevelStatus(int)));
    connect(m_policyKit, SIGNAL(notifySystemLevelStatusChangeResult(bool, int)), this, SLOT(showDialog(bool, int)));
    m_polKitThread.start();

    connect(m_securityLevelModel, SIGNAL(notifySystemLevelChangeFinish(bool, int)), this, SLOT(acceptSystemLevelChangeFinish(bool, int)));
}

SecurityLevelWidget::~SecurityLevelWidget()
{
    m_policyKit->deleteLater();
    m_policyKit = nullptr;

    m_polKitThread.quit();
    m_polKitThread.wait();
}

// 初始化界面
void SecurityLevelWidget::initUI()
{
    setLayout(m_layout);

    // 添加滑动条区域
    QScrollArea *scrollArea = new QScrollArea(this);
    scrollArea->setAccessibleName("securityLevelWidget_scrollArea");
    scrollArea->viewport()->setAccessibleName("scrollArea_viewWidget");
    scrollArea->setFrameShape(QFrame::Shape::NoFrame);
    scrollArea->setWidgetResizable(true);
    scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarPolicy::ScrollBarAlwaysOff);
    m_layout->addWidget(scrollArea);

//    // 触屏移动
//    QScroller::grabGesture(scrollArea->viewport(), QScroller::LeftMouseButtonGesture);
//    QScroller *scroller = QScroller::scroller(scrollArea);
//    QScrollerProperties sp;
//    sp.setScrollMetric(QScrollerProperties::HorizontalOvershootPolicy, QScrollerProperties::OvershootAlwaysOff);
//    scroller->setScrollerProperties(sp);

    // 将mainWidget设置为滑动区域的主窗口
    QWidget *scrollAreaWidget = new QWidget(scrollArea);
    scrollAreaWidget->setFixedWidth(715); //设置固定宽度
    scrollAreaWidget->setAccessibleName("viewWidget_contentWidget");
    scrollArea->setWidget(scrollAreaWidget);

    // 设置滑动条区域布局器
    QVBoxLayout *scrollAreaLayout = new QVBoxLayout;
    scrollAreaLayout->setContentsMargins(0, 0, 0, 0);
    scrollAreaWidget->setLayout(scrollAreaLayout);
    scrollAreaLayout->addSpacing(50);

    // 标题
    QLabel *title = new QLabel(tr("Security Level"), this);
    title->setContentsMargins(45, 0, 0, 0);
    title->setAccessibleName("contentWidget_titleLable");
    QFont ft = title->font();
    ft.setBold(true);
    title->setFont(ft);
//    DFontSizeManager::instance()->bind(title, DFontSizeManager::T5);
    scrollAreaLayout->setSpacing(0);
    scrollAreaLayout->addWidget(title, 0, Qt::AlignLeft | Qt::AlignTop);
    scrollAreaLayout->setAlignment(Qt::AlignTop);

    // 标题底下提示
    scrollAreaLayout->addSpacing(8);
    QLabel *tipLabel = new QLabel("", this);
    tipLabel->setAccessibleName("contentWidget_tipLable");
    tipLabel->setContentsMargins(45, 0, 0, 0);
    tipLabel->setText(tr("Choose a proper system security level according to usage scenarios"));
//    tipLabel->setElideMode(Qt::ElideMiddle); // 设置显示不够，中间省略
//    DFontSizeManager::instance()->bind(tipLabel, DFontSizeManager::SizeType::T8);
    scrollAreaLayout->addWidget(tipLabel, 0, Qt::AlignLeft | Qt::AlignTop);

    // 密码限制等级
    scrollAreaLayout->addSpacing(30);
    m_highLevelItem = new SecurityLevelItem(this);
//    if (m_securityLevelModel->isShowHighLevel() && DSysInfo::UosType::UosServer != SystemType) {
        m_highLevelItem->setAccessibleName("contentWidget_highLevelFrame");
        m_highLevelItem->setAccessibleParentText("highLevelFrame");
        m_highLevelItem->setIcon(QIcon::fromTheme("dcc_security_level_high"));
        m_highLevelItem->setLevelText(tr("High"));
        m_highLevelItem->setTipText(tr("Privilege separation for scenarios with high security requirements"));
        m_highLevelItem->setTipLabelTextWordWrap(false);
        m_highLevelItem->setTipLabelTextElideMode(Qt::ElideMiddle);

        m_highLevelItem->setWarningText(tr("If enabled, apps not configured with permission policies will become unavailable"));
        scrollAreaLayout->addWidget(m_highLevelItem);
//    } else {
//        m_highLevelItem->setVisible(false);
//    }

    scrollAreaLayout->addSpacing(10);
    m_mediumLevelItem = new SecurityLevelItem(this);
    //    m_mediumLevelItem->setFixedHeight(62);
    m_mediumLevelItem->setAccessibleName("contentWidget_mediumLevelFrame");
    m_mediumLevelItem->setAccessibleParentText("mediumLevelFrame");
    m_mediumLevelItem->setIcon(QIcon::fromTheme("dcc_security_level_medium"));
    m_mediumLevelItem->setLevelText(tr("Medium"));
    m_mediumLevelItem->setTipText(tr("Basic system and network protection for general working scenarios"));
    m_mediumLevelItem->setTipLabelTextWordWrap(false);
    m_mediumLevelItem->setTipLabelTextElideMode(Qt::ElideMiddle);
    scrollAreaLayout->addWidget(m_mediumLevelItem);

    scrollAreaLayout->addSpacing(10);
    m_lowLevelItem = new SecurityLevelItem(this);
    //    m_lowLevelItem->setFixedHeight(62);
    m_lowLevelItem->setAccessibleName("contentWidget_lowLevelFrame");
    m_lowLevelItem->setAccessibleParentText("lowLevelFrame");
    m_lowLevelItem->setIcon(QIcon::fromTheme("dcc_security_level_low"));
    m_lowLevelItem->setLevelText(tr("Low"));
    m_lowLevelItem->setTipText(tr("Basic system protection for trusted environments"));
    m_lowLevelItem->setTipLabelTextWordWrap(false);
    m_lowLevelItem->setTipLabelTextElideMode(Qt::ElideMiddle);
    scrollAreaLayout->addWidget(m_lowLevelItem);

    scrollAreaLayout->addStretch(0);

    // 等级设置
    showSelectItemIcon(m_securityLevelModel->getSystemSafeLevel());

    // 连接信号槽
    connect(m_highLevelItem, SIGNAL(clicked()), this, SLOT(highLevelItemClicked()));
    connect(m_mediumLevelItem, SIGNAL(clicked()), this,  SLOT(mediumLevelItemClicked()));
    connect(m_lowLevelItem, SIGNAL(clicked()), this,  SLOT(lowLevelItemClicked()));
}

// item选中图标显示
void SecurityLevelWidget::showSelectItemIcon(int nType)
{
    m_nSaveItemType = nType;
    // 选择图标显示
    if (SYSTEM_SAFE_LEVEL_LOW == nType) {
        m_highLevelItem->setSelected(false);
        m_mediumLevelItem->setSelected(false);
        m_lowLevelItem->setSelected(true);
    } else if (SYSTEM_SAFE_LEVEL_MID == nType) {
        m_highLevelItem->setSelected(false);
        m_mediumLevelItem->setSelected(true);
        m_lowLevelItem->setSelected(false);
    } else if (SYSTEM_SAFE_LEVEL_HIGH == nType) {
        m_highLevelItem->setSelected(true);
        m_mediumLevelItem->setSelected(false);
        m_lowLevelItem->setSelected(false);
    }
}

// 验证权限
void SecurityLevelWidget::verifyPermission(int nType)
{
    int nSaveType = m_securityLevelModel->getSystemSafeLevel();
    if (nType != nSaveType) {
        this->parentWidget()->parentWidget()->parentWidget()->setEnabled(false);
        Q_EMIT requestConfirmChangeSystemLevel(nType);
    }
}

// 显示切换弹框
void SecurityLevelWidget::showDialog(bool isResult, int type)
{
    this->parentWidget()->parentWidget()->parentWidget()->setEnabled(true);
    int nSaveType = m_securityLevelModel->getSystemSafeLevel();
    if (isResult) {
        if (SYSTEM_SAFE_LEVEL_HIGH == nSaveType) {
            if (m_securityLevelModel->getIsWaylandDisplay()) {
                // 提示wayland无法切换
                WaylandWarningDialog *waylandDlg = new WaylandWarningDialog(this);
                waylandDlg->raise();
                waylandDlg->show();
                showSelectItemIcon(nSaveType);
                return;
            }
            // 只有安全管理员才关闭等保
            if (SYSTEM_SAFE_LEVEL_SECADM_NAME != m_securityLevelModel->getCurrentUserName()) {
                if ((SYSTEM_SAFE_LEVEL_MID == type) || (SYSTEM_SAFE_LEVEL_LOW == type)) {
                    showSecurityAdminDialog();
                    showSelectItemIcon(nSaveType);
                    return;
                }
            }
        }

        int type;
        if (SYSTEM_SAFE_LEVEL_HIGH == type) {
            // 低和中 - 高
            type = SecurityLevelChangeType::LMtoHigh;
        } else if (SYSTEM_SAFE_LEVEL_MID == type && SYSTEM_SAFE_LEVEL_LOW == nSaveType) {
            // 低 - 中
            type = SecurityLevelChangeType::LtoMedium;
        } else if (SYSTEM_SAFE_LEVEL_LOW == type && SYSTEM_SAFE_LEVEL_MID == nSaveType) {
            // 中 - 低
            type = SecurityLevelChangeType::MtoLow;
        } else if (SYSTEM_SAFE_LEVEL_MID == type && SYSTEM_SAFE_LEVEL_HIGH == nSaveType) {
            // 高 - 中
            type = SecurityLevelChangeType::HtoMedium;
        } else if (SYSTEM_SAFE_LEVEL_LOW == type && SYSTEM_SAFE_LEVEL_HIGH == nSaveType) {
            // 高 - 低
            type = SecurityLevelChangeType::HtoLow;
        }
        SecurityLevelChangeDialog *slcdlg = new SecurityLevelChangeDialog(type, this);
        connect(slcdlg, SIGNAL(notifyDialogFinish()), this, SLOT(showLevelPasswordDialog()));
        connect(slcdlg, SIGNAL(notifyDialogClose()), this, SLOT(showSelectItemIconHelp()));
        slcdlg->raise();
        slcdlg->show();
    } else {
        showSelectItemIcon(nSaveType);
    }
}

// 三权账户密码输入弹框
void SecurityLevelWidget::showLevelPasswordDialog()
{
    PrivilegeSeparationDialog *psdlg = new PrivilegeSeparationDialog(this);
    connect(psdlg, SIGNAL(notifyDialogFinish()), this, SLOT(showSystemLevelOnDialog()));
    connect(psdlg, SIGNAL(notifyDialogClose()), this, SLOT(showSelectItemIconHelp()));
    psdlg->raise();
    psdlg->show();
}

// 显示开启等保正在配置弹框
void SecurityLevelWidget::showSystemLevelOnDialog(const QString &sSysadmPassword, const QString &sSecadmPassword, const QString &sAudadmPassword)
{
    m_securityLevelModel->setSystemLevel(m_nSaveItemType, true, true, sSysadmPassword, sSecadmPassword, sAudadmPassword);
    m_systemLevelStartDialog = new ConfiguratingSystemLevelDialog(this);
    m_systemLevelStartDialog->raise();
    m_systemLevelStartDialog->show();
}

// 等保开启关闭执行完成弹框
void SecurityLevelWidget::acceptSystemLevelChangeFinish(bool isSuccess, int nType)
{
    if (SYSTEM_SAFE_LEVEL_HIGH == nType && m_systemLevelStartDialog != nullptr) {
        if (!isSuccess) {
            showSelectItemIcon(m_securityLevelModel->getSystemSafeLevel());
        }
        m_systemLevelStartDialog->close();
        m_systemLevelStartDialog = nullptr;
    } else if (SYSTEM_SAFE_LEVEL_HIGH != nType && m_executingDialog != nullptr) {
        if (!isSuccess) {
            showSelectItemIcon(m_securityLevelModel->getSystemSafeLevel());
        }
        m_executingDialog->close();
        m_executingDialog = nullptr;
    }
}

// 系统安全等级切换 - 除开启/关闭等保
void SecurityLevelWidget::acceptSystemLevelChange()
{
    m_securityLevelModel->setSystemLevelChange(m_nSaveItemType);
}

// 系统安全等级切换 -- 关闭等保
void SecurityLevelWidget::acceptSystemLevelClose()
{
    m_securityLevelModel->setSystemLevel(m_nSaveItemType, false, false, "", "", "");
    m_executingDialog = new ExecutingDialog(this);
    m_executingDialog->raise();
    m_executingDialog->show();
}

void SecurityLevelWidget::highLevelItemClicked()
{
    showSelectItemIcon(SYSTEM_SAFE_LEVEL_HIGH);
    verifyPermission(SYSTEM_SAFE_LEVEL_HIGH);
}

void SecurityLevelWidget::mediumLevelItemClicked()
{
    showSelectItemIcon(SYSTEM_SAFE_LEVEL_MID);
    verifyPermission(SYSTEM_SAFE_LEVEL_MID);
}

void SecurityLevelWidget::lowLevelItemClicked()
{
    showSelectItemIcon(SYSTEM_SAFE_LEVEL_LOW);
    verifyPermission(SYSTEM_SAFE_LEVEL_LOW);
}

void SecurityLevelWidget::showSelectItemIconHelp()
{
    showSelectItemIcon(m_securityLevelModel->getSystemSafeLevel());
}

// 只有安全管理员才允许降级弹框
void SecurityLevelWidget::showSecurityAdminDialog()
{
    SwitchAccountTipDialog *satdlg = new SwitchAccountTipDialog(this);
    satdlg->raise();
    satdlg->show();
}
